﻿using Autofac;
using AutoMapper;
using Serilog;
using SqlSugar;
using WCS_Core_Configuration;
using WCS_Entity.AutoQeuipment;
using WCS_Entity.Dto.AutoEquipmentDto;
using WCS_Entity.Model;
using WCS_Repository.Interface;
using WCS_Service.DomianService.Interface;
using WCS_Service.DomianService.Models;
using WCS_Service.Interface;
using WCS_Utility.ConstString;
using WCS_Utility.Extensions;

namespace WCS_Service.Services
{
    /// <summary>
    /// 自动化设备服务启动暂停管理
    /// </summary>
    public class AutoEquipmentOperateService : BaseService<AutoEquipmentsEntity>, IAutoEquipmentOperateService
    {
        private readonly IAutoEquipmentRepository _autoEquipmentRepository;
        private readonly IComProtocolRepository _comProtocolRepository;
        private readonly IComponentContext _componentContext;
        private readonly IComControl _comControl;
        private readonly IMapper _mapper;

        public AutoEquipmentOperateService(IAutoEquipmentRepository autoEquipmentRepository,
                                           IComProtocolRepository comProtocolRepository,
                                           IComControl comControl,
                                           IComponentContext componentContext,
                                           IMapper mapper)
        {
            _autoEquipmentRepository = autoEquipmentRepository;
            _comProtocolRepository = comProtocolRepository;
            _comControl = comControl;
            _componentContext = componentContext;
            _mapper = mapper;
        }

        #region 自动化设备服务操作
        public async Task<bool?> CreatAutoEquipmentServiceAsync(int id, bool isManual = true)
        {
            if (!await _comControl.ServiceCreateCheckAsync(id))
            {
                Log.Error($"启动设备通信服务{id}该设备服务已经启动");
                return null;
            }
            var eqInfo = await _autoEquipmentRepository.QueryByIdAsync(id);
            if (eqInfo is null)
            {
                Log.Error($"启动设备通信服务{id}该设备不存在");
                return false;
            }
            if (eqInfo.status == ConstStringData.Deactivate)
            {
                Log.Error($"启动设备已经停用");
                return false;
            }
            if (string.IsNullOrEmpty(eqInfo.comType))
            {
                Log.Error($"启动设备通信类型未配置");
                return false;
            }
            if (eqInfo.equipmentType == ConstStringData.AGV_eq)
            {
                Log.Error($"启动设备为AGV，通信通过RCS服务建立");
                return false;   
            }
            var protocolList = await _comProtocolRepository.QueryListByClauseAsync(p => p.protocolType == eqInfo.protocolType);

            if (protocolList is null || !protocolList.Any())
            {
                Log.Error($"启动设备通信服务{id}该设备通信协议不存在");
                return false;
            }
            //创建通信协议服务
            ComInitParaModel paraModel = new ComInitParaModel();
            paraModel.comType = eqInfo.comType.StringToEnum();
            paraModel.AutoEquipmentId = eqInfo.id;
            paraModel.serviceName = eqInfo.equipmentNumber;
            paraModel.equipmentType = eqInfo.equipmentType;
            paraModel.ip = eqInfo.ip;
            paraModel.port = eqInfo.port;
            paraModel.areaCode = eqInfo.AreaCode;
            paraModel.protocolMsgList = protocolList;
            var flag = await _comControl.CreateComServiceAsync(paraModel, isManual);
            return flag;
        }
        public async Task<Dictionary<int,bool>> CreatBatchAutoEquipmentServiceAsync(List<int> ids, bool isManual = true)
        {
            var eqInfos = await _autoEquipmentRepository.QueryByIDsAsync(ids.ToArray());
            if (eqInfos is null || !eqInfos.Any())
            {
                Log.Error($"启动批量设备通信服务,设备不存在");
                return null;
            }
            List<Task<(int,bool)>> subFlags = new();
            foreach (var item in eqInfos)
            {
                if (!string.IsNullOrEmpty(item.comType) && item.equipmentType != ConstStringData.AGV_eq)
                {
                    subFlags.Add(CetProtocolAsync(item, isManual));
                }
            }
            await Task.WhenAll(subFlags);
            var data = subFlags.Where(s => s.Result.Item1 != 0)?.Select(u => u.Result).ToDictionary<int, bool>();
            if (data is null)
            {
                Log.Error($"启动批量设备通信服务失败");
                return null;
            }
            return data;
        }
        /// <summary>
        /// 批量启动自动化设备不需要返回结果
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="isManual"></param>
        /// <returns></returns>
        public async Task CreatBatchAutoEquipmentNoResultAsync(List<int> ids, Func<AutoEquipmentDto, Task> addProcess, bool isManual = true)
        {
            var eqInfos = await _autoEquipmentRepository.QueryByIDsAsync(ids.ToArray());
            if (eqInfos is null || !eqInfos.Any())
            {
                Log.Error($"启动批量设备通信服务,设备不存在");
                return;
            }
            List<Task> subFlags = new();
            foreach (var item in eqInfos)
            {
                if (!string.IsNullOrEmpty(item.comType) && item.equipmentType != ConstStringData.AGV_eq)
                {
                    subFlags.Add(CetProtocolNoResultAsync(item, isManual, addProcess));
                }
            }
            await Task.WhenAll(subFlags);
        }

        public async Task<List<RunAutoEquipmentInfoDto>> GetRunningAutoEquipmenServiceAsync()
        {
            List<RunAutoEquipmentInfoDto> result = new List<RunAutoEquipmentInfoDto>();
            return await _comControl.GetAllRunServiceInfoAsync();
        }

        public async Task<bool> StopAutoEquipmentServiceAsync(int id)
        {
            return false;
        }
        public async Task<bool> StopBatchAutoEquipmentServiceAsync(List<int> id)
        {
            return false;
        }
        /// <summary>
        /// 获取正在运行的AGV信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<ManageAgvModel>> GetAgvInfoAsync()
        {
            if (!_componentContext.TryResolve<IWCSMainControlManage>(out IWCSMainControlManage instance))
            {
                Log.Error($"主控服务获取失败！");
                return null;
            }
            var service = instance.QueryAGVService();
            if (service is null)
            {
                Log.Error($"AGV服务获取失败！");
                return null;
            }
            return await service.QueryAllAgvInfoBaseAsync();
        }
        #endregion

        #region private 
        private async Task CetProtocolNoResultAsync(AutoEquipmentsEntity entity, bool isManual, Func<AutoEquipmentDto, Task> addProcess)
        {
            var protocolList = await _comProtocolRepository.QueryListByClauseAsync(p => p.protocolType == entity.protocolType);
            if (protocolList is null)
            {
                Log.Error($"启动设备通信服务{entity.id}该设备通信协议不存在");
                return;
            }
            //启动通信服务
            //创建通信协议服务
            ComInitParaModel paraModel = new ComInitParaModel();
            paraModel.comType = entity.comType.StringToEnum();
            paraModel.AutoEquipmentId = entity.id;
            paraModel.serviceName = entity.equipmentNumber;
            paraModel.equipmentType = entity.equipmentType;
            paraModel.ip = entity.ip;
            paraModel.port = entity.port;
            paraModel.areaCode = entity.AreaCode;
            paraModel.protocolMsgList = protocolList;
            var flag = await _comControl.CreateComServiceAsync(paraModel, isManual);
            //启动成功将改设备添加至对应设备的服务管理中
            if (flag)
            {
                var dto = _mapper.Map<AutoEquipmentDto>(entity);
                if (dto is not null)
                {
                    await addProcess(dto);
                }
            }
        }

        private async Task<(int,bool)> CetProtocolAsync(AutoEquipmentsEntity entity,bool isManual)
        {
            var protocolList = await _comProtocolRepository.QueryListByClauseAsync(p => p.protocolType == entity.protocolType);
            if (protocolList is null)
            {
                Log.Error($"启动设备通信服务{entity.id}该设备通信协议不存在");
                return (0, false);
            }
            //启动通信服务
            //创建通信协议服务
            ComInitParaModel paraModel = new ComInitParaModel();
            paraModel.comType = entity.comType.StringToEnum();
            paraModel.AutoEquipmentId = entity.id;
            paraModel.serviceName = entity.equipmentNumber;
            paraModel.equipmentType = entity.equipmentType;
            paraModel.ip = entity.ip;
            paraModel.port = entity.port;
            paraModel.areaCode = entity.AreaCode;
            paraModel.protocolMsgList = protocolList;
            var flag = await _comControl.CreateComServiceAsync(paraModel, isManual);
            return (entity.id, flag);
        }
        #endregion
    }
}
